package com.ccl.iot.object;

import java.util.Arrays;
import java.util.HashMap;

import com.ccl.iot.privates.ListMap;

public class IOTSyncArray implements IOTAbsSyncObject {
	public static final String KSYNC_INFO_PREFIX = KSYNC_INFO_PREFIX_BASE + "[";
	
	private static long gID = 1;
	
	/*
	 * 	Non-static functions
	 */
	private long iID = gID++;
	private String iSyncID = null;
	private IOTSyncObjectCollector iCollector = null;
	
	private Object iArray[] = null;
	
	public IOTSyncArray(Object aArray[]){
		iArray = aArray;
	}
	
	public IOTSyncArray(IOTSyncObjectInfo aSyncInfo, IOTSyncObjectCollector aCollector) {
		setSyncInfo(aSyncInfo, aCollector);
	}
	
	public int getArraySize(){
		return iArray != null ? iArray.length : 0;
	}
	
	public void setArray(Object aArray[]){
		if (aArray != iArray){
			notifyBeforeObjectChange(this);
			
			iArray = aArray;
			
			notifyObjectChange(this);
		}
	}
	
	public Object[] getArray(){
		return iArray;
	}
	
	@Override
	public long getID() {
		return iID;
	}
	
	@Override
	public String getSyncInfoPrefix() {
		return KSYNC_INFO_PREFIX;
	}
	
	@Override
	public String getSyncID() {
		if (iSyncID == null){
			return IOTInfoHeader.Encode(KSYNC_INFO_PREFIX, iID, null);
		}else{
			return iSyncID;
		}
	}
	
	@Override
	public void setSyncCollector(IOTSyncObjectCollector aCollector) {
		iCollector = aCollector;
	}
	
	@Override
	public void setSyncInfo(IOTSyncObjectInfo aSyncInfo, IOTSyncObjectCollector aCollector) {
		setSyncCollector(aCollector);
		
		if (aSyncInfo != null && aSyncInfo.isValid()){
			ListMap<String, Object> tInfos = aSyncInfo.getAllInfo();
			
			iID = aSyncInfo.getLongID();
			iSyncID = aSyncInfo.getID();
			
			if (tInfos != null){
				int tCount = tInfos.size();
				
				if (tCount > 0){
					iArray = new Object[tCount];
					
					for (int i = 0; i < tCount; i++){
						String tKey = tInfos.getKeyAt(i);
						Object tObject = tInfos.getValueAt(i);
						
						if (tObject instanceof IOTSyncObjectInfo){
							if (aCollector != null){
								tObject = aCollector.findObject(((IOTSyncObjectInfo)tObject).getID());
							}else{
								tObject = null;
							}
						}
						
						if (tObject != null){
							setParameter(tKey, tObject);
						}
					}
				}
			}
		}
	}

	@Override
	public HashMap<String, Object> getSyncInfos() {
		if (iArray != null){
			HashMap<String, Object> tInfos = new HashMap<String, Object>();
			
			for (int i = 0; i < iArray.length; i++){
				Object tObject = iArray[i];
				
				if (tObject != null){
					tInfos.put(String.valueOf(i), tObject);
				}
			}
			
			return tInfos;
		}
		
		return null;
	}

	@Override
	public Object[] getSyncObjects() {
		return iArray;
	}
	
	@Override
	public boolean setParameter(String aKey, Object aObject) {
		if (aKey != null && iArray != null){
			int tIndex = Integer.valueOf(aKey);
			
			if (tIndex >= 0 && tIndex < iArray.length){
				iArray[tIndex] = aObject;
				
				return true;
			}
		}
		
		return false;
	}

	@Override
	public String toString() {
		if (iArray != null){
			return Arrays.toString(iArray);
		}
		
		return super.toString();
	}
	
	public void notifyBeforeObjectChange(IOTAbsSyncObject aObject){
		if (iCollector != null){
			iCollector.remove(aObject);
		}
	}
	
	public void notifyObjectChange(IOTAbsSyncObject aObject){
		if (iCollector != null){
			iCollector.add(aObject);
		}
	}

}
